package com.diankangwo.controller;

import com.diankangwo.constant.PayStatus;
import com.diankangwo.constant.resultMsg;
import com.diankangwo.dao.*;
import com.diankangwo.domain.*;
import com.diankangwo.service.RefundMoneyService;
import com.diankangwo.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

/**
 * 购物订单控制器
 *
 * @author xiaoyu
 */
@Controller
@Api(description = "购物订单")
public class OrderController {

    @Autowired
    private UserDAO userDao;

    @Autowired
    private OrderDAO orderDao;

    @Autowired
    private ShoppingCartDAO shoppingCartDao;

    @Autowired
    private CommodityDAO commDao;

    @Autowired
    private AddressDAO addressDao;

    @Autowired
    private OnlinePayLogDAO onlinePayLogDAO;

    @Autowired
    private ExpressCodeDAO expressCodeDAO;

    @Autowired
    private OrderDAO orderDAO;
    @Autowired
    private RefundMoneyService refundMoneyService;// 注入services

    @Autowired
    private PropertyDAO propertyDAO;

    @Autowired
    private IntegralDAO integralDAO;

    // 日志记录
    private static final Logger LOG = Logger.getLogger(UserController.class);

    /**
     * 创建商品订单
     *
     * @param accessToken token
     * @param addressID   收货地址ID
     * @param couponID    使用用户领取的优惠券ID
     * @param cartDataID  购物车数据ID
     * @param bill        是否开发票 1为是 0为否
     * @param billType    发票类型 enterprise 企业 personal 个人
     * @param billContent 公式名称或个人名称
     * @param orderChanel 下单渠道
     * @return json
     */
    @ApiOperation(value = " 创建商品订单", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "addressID", value = "收货地址ID", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "couponID", value = "使用用户领取的优惠券ID", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "cartDataID", value = "购物车数据ID", required = true, dataType = "String"),
            @ApiImplicitParam(name = "bill", value = "是否开发票 1为是 0为否", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "billType", value = "发票类型 enterprise 企业 personal 个人", required = true, dataType = "String"),
            @ApiImplicitParam(name = "billContent", value = "公式名称或个人名称", required = true, dataType = "String"),
            @ApiImplicitParam(name = "orderChanel", value = "下单渠道", required = true, dataType = "String")
    })
    @ResponseBody
    @RequestMapping(value = "/order", method = RequestMethod.POST)
    public String orderCreate(String accessToken, Integer addressID, Integer couponID, String cartDataID, Integer bill, String billType, String billContent, String orderChanel, int isIntegral) {
        UserInfo user = userDao.getUserByToken(accessToken);
        Order order = new Order();
        String code = "2";
        String msg = "处理异常！";
        if (user != null) {
            order.setUid(user.getUid());
            Address address = addressDao.find(addressID);
            if (address != null) {
                //查询地址信息
                Province pv = address.getProvinceId();
                District dr = address.getDistrictId();
                City city = address.getCityId();
                //为订单赋值
                order.setProvince(pv.getProvinceName());
                order.setProvinceID(pv.getProvinceID());
                order.setCity(city.getCityName());
                order.setCityID(city.getCityID());
                order.setArea(dr.getDistrictName());
                order.setAreaID(dr.getDistrictID());
                order.setAddress(address.getDetailedAddress());
                order.setUid(user.getUid());
                order.setCreateDate(new Date());
                order.setOrderNo(OrderUtil.getOrderNo());
                order.setCoiUid(GuidUtil.getGuid());
                order.setOrderStatus(PayStatus.unpaid.getName());
                order.setOrderNo(OrderUtil.getOrderNo());
                order.setUpdateDate(new Date());
                order.setUpdateUser(user.getUsername());
                order.setIsPay("0");
                order.setUserName(address.getUsername());
                order.setUserPhone(user.getTel());
                order.setOrderChanel(orderChanel);
                order.setType("commodity");
                order.setState(0);
                List<Commodity> cList = new ArrayList<Commodity>();
                List<ShoppingCart> scList = new ArrayList<ShoppingCart>();
                int totalFee = 0;
                //查询购物车中得订单信息
                JSONArray json = JSONArray.fromObject(cartDataID); // 首先把字符串转成 JSONArray 对象
                List l = JSONArray.toList(json);
                for (Object object : l) {
                    Commodity c = new Commodity();
                    //查询购物车数据
                    ShoppingCart sc = shoppingCartDao.find((int) object);
                    scList.add(sc);
                    c = commDao.find(sc.getCommodityId());
                    //判断库存是否充足
                    JSONArray jsonArray = JSONArray.fromObject(sc.getSelected());
                    List jsonObject = JSONArray.toList(jsonArray);
                    for (Object o : jsonObject) {
                        JSONObject jo = JSONObject.fromObject(o);
                        Property property = propertyDAO.find(Integer.parseInt(jo.get("propertiesID").toString()));
                        if (sc.getCommodityNumber() > Integer.parseInt(property.getPropertyNum())) {
                            code = "2";
                            msg = property.getPropertyValue() + "：库存不足，无法购买！";
                            return resultMsg.mapToJson(code, msg, null);
                        }
                    }
                    //判断购买用户时候是端口用户
                    if (user.isPort()) {
                        //计算商品总金额
                        int money = (int) (c.getCommodityPriceUser() * 100) * sc.getCommodityNumber() + (int) (c.getFreight() * 100);
                        //累计总金额
                        totalFee = totalFee + money;
                    } else {
                        //计算商品总金额
                        int money = (int) (c.getCommodityPriceShop() * 100) * sc.getCommodityNumber() + (int) (c.getFreight() * 100);
                        //累计总金额
                        totalFee = totalFee + money;
                    }
                    //判断是否使用积分
                    if (isIntegral == 1 && l.size() == 1) {
                        order.setCouponID(1);
                        //可抵用积分
                        float integralTotal = user.getIntegral() / c.getIntegralConsumptionRatio();
                        //最多抵扣积分
                        int integralLimit = c.getIntegralSpendingLimit() / c.getIntegralConsumptionRatio();

                        //int num = c.getIntegralSpendingLimit()-(int) integralTotal * 100;
                        if (integralTotal > 0) {
                            if (integralLimit > (int) integralTotal) {
                                totalFee = totalFee - (int) integralTotal * 100;
//                                user.setIntegral(user.getIntegral() - (int) integralTotal * c.getIntegralConsumptionRatio());
//                                userDao.updateUser(user);
//                                //存入积分明细
//                                Integral integral = new Integral();
//                                Timestamp ts = new Timestamp(System.currentTimeMillis());
//                                integral.setDate(ts);
//                                integral.setMoney(integralTotal);
//                                integral.setText("购买" + c.getCommodityName() + "抵用积分：" + (int) integralTotal * c.getIntegralConsumptionRatio());
//                                integral.setUid(user.getUid());
//                                integralDAO.saveOrUpdate(integral);
                            } else {
                                totalFee = totalFee - integralLimit * 100;
//                                user.setIntegral(user.getIntegral() - integralLimit * c.getIntegralConsumptionRatio());
//                                userDao.updateUser(user);
//                                //存入积分明细
//                                Integral integral = new Integral();
//                                Timestamp ts = new Timestamp(System.currentTimeMillis());
//                                integral.setDate(ts);
//                                integral.setMoney(integralLimit);
//                                integral.setText("购买" + c.getCommodityName() + "抵用积分：" + (int) integralLimit * c.getIntegralConsumptionRatio());
//                                integral.setUid(user.getUid());
//                                integralDAO.saveOrUpdate(integral);
                            }
                        }
                    }
                    cList.add(c);
                    sc.setStatus(1);
                    shoppingCartDao.saveOrUpdate(sc);
                }
                order.setShoppingCarts(scList);
                order.setTotalFee(totalFee);
                order.setBill(bill);
                order.setBillType(billType);
                order.setBillContent(billContent);
                order = orderDao.saveOrUpdate(order);
                //存入支付数据
                OnlinePayLog opl = new OnlinePayLog();
                opl.setCreateDate(new Date());
                opl.setBillNo(order.getOrderNo());
                opl.setCreateUser(user.getUsername());
                opl.setIdKey(GuidUtil.getGuid());
                opl.setPayStatus(PayStatus.unpaid.getName());
                opl.setPayType(order.getPayType());
                opl.setTitle(order.getShoppingCarts().get(0).getCommodityName());
                opl.setTotalFee(order.getTotalFee());
                onlinePayLogDAO.saveOrUpdate(opl);
            }
            code = "1";
            msg = "订单创建成功！！";
        } else {
            msg = "未查询到用户信息！";
        }
        return resultMsg.mapToJson(code, msg, order);
    }

    /**
     * 查询单条订单的详情信息
     *
     * @param accessToken token
     * @param id          订单ID
     * @return
     */
    @ApiOperation(value = " 查询单条订单的详情信息", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "id", value = "订单ID", required = true, dataType = "Integer")
    })
    @ResponseBody
    @RequestMapping(value = "/order", method = RequestMethod.GET)
    public String find(String accessToken, Integer id) {
        UserInfo user = userDao.getUserByToken(accessToken);
        String code = "2";
        String msg = "处理异常！";
        Order order = new Order();
        if (user != null) {
            order = orderDao.find(id);
            if (order != null) {
                code = "1";
                msg = "查询成功！";
            }
        } else {
            msg = "未查询到用户信息！";
        }
        return resultMsg.mapToJson(code, msg, order);
    }

    /**
     * 获取我的订单列表
     *
     * @param accessToken token
     * @param statu       订单状态
     * @return
     */
    @ApiOperation(value = " 获取我的订单列表", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "statu", value = "订单状态", required = true, dataType = "String")
    })
    @ResponseBody
    @RequestMapping(value = "/order/list", method = RequestMethod.GET)
    public String getOrderList(String accessToken, String statu, int pageNo, int pageSize) {
        UserInfo user = userDao.getUserByToken(accessToken);
        String code = "2";
        String msg = "处理异常！";
        PageSupport<Order> orderList = null;
        if (user != null) {
            orderList = orderDao.findByStatu(statu, user.getUid(), pageNo, pageSize);
            code = "1";
            if (orderList != null) {
                msg = "查询成功！";
            } else {
                msg = "未查询到订单数据！";
            }
        } else {
            msg = "未查询到用户信息！";
        }
        return resultMsg.mapToJson(code, msg, orderList == null ? null : orderList.getResultData());
    }

    /**
     * 获取我的订单列表
     *
     * @param accessToken token
     * @return
     */
    @ApiOperation(value = " 获取我的订单列表", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "statu", value = "订单状态", required = true, dataType = "String")
    })
    @ResponseBody
    @RequestMapping(value = "/order/num", method = RequestMethod.GET)
    public String getOrderNum(String accessToken) {
        Map<String, Object> map = new HashMap<>();
        UserInfo user = userDao.getUserByToken(accessToken);
        String code = "2";
        String msg = "处理异常！";
        if (user != null) {
            map.put("unpaid", orderDao.findByStatu("unpaid", user.getUid(), 1, Integer.MAX_VALUE) == null ? 0 : orderDao.findByStatu("unpaid", user.getUid(), 1, Integer.MAX_VALUE).getResultData().size());
            map.put("beforedeliver", orderDao.findByStatu("beforedeliver", user.getUid(), 1, Integer.MAX_VALUE)  == null ? 0 : orderDao.findByStatu("beforedeliver", user.getUid(), 1, Integer.MAX_VALUE).getResultData().size());
            map.put("uncommented", orderDao.findByStatu("uncommented", user.getUid(), 1, Integer.MAX_VALUE) == null ? 0 : orderDao.findByStatu("uncommented", user.getUid(), 1, Integer.MAX_VALUE).getResultData().size());
            map.put("refund", orderDao.findByStatu("refund", user.getUid(), 1, Integer.MAX_VALUE) == null ? 0 : orderDao.findByStatu("refund", user.getUid(), 1, Integer.MAX_VALUE).getResultData().size());
            code = "1";
            msg = "查询成功!";
        } else {
            msg = "未查询到用户信息！";
        }
        return resultMsg.mapToJson(code, msg, map);
    }

    /**
     * 删除我的订单
     *
     * @param accessToken token
     * @param id          订单ID
     * @return
     */
    @ApiOperation(value = " 删除我的订单", notes = "")
    @ResponseBody
    @RequestMapping(value = "/order/del", method = RequestMethod.POST)
    public String delOrder(String accessToken, String id) {
        UserInfo user = userDao.getUserByToken(accessToken);
        String code = "2";
        String msg = "处理异常!";
        if (user != null) {
            orderDao.deleteById(id);
            code = "1";
            msg = "删除成功！";
        } else {
            msg = "系统异常，删除失败！";
        }
        return resultMsg.mapToJson(code, msg, null);
    }

    /**
     * 获取物流信息
     *
     * @param id 订单ID
     * @return
     */
    @ApiOperation(value = " 获取物流信息", notes = "")
    @ResponseBody
    @RequestMapping(value = "/order/expree", method = RequestMethod.POST)
    public String expree(String id) {
        String code = "2";
        String msg = "处理异常!";
        Order order = orderDao.findByOrderNo(id);
        Map<String, Object> map = new HashMap<>();
        if (order != null) {
            List<ExpressCode> expressCodeList = expressCodeDAO.findByName(order.getWuliuType());
            if (expressCodeList.size() > 0) {
                code = "1";
                kdnAPI api = new kdnAPI();
                try {
                    msg = "查询物流信息成功！";
                    map.put("result", api.orderTracesSubByJson(expressCodeList.get(0).getCode(), order.getWuliuOrderNo()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                code = "2";
                msg = "未查询到物流信息！";
            }
        } else {
            msg = "未查询到订单信息！";
        }
        return resultMsg.mapToJson(code, msg, map);
    }

    /**
     * 申请退款
     *
     * @param accessToken token
     * @return
     */
    @ApiOperation(value = " 申请退款", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "fundCause", value = "订单号", required = true, dataType = "String")
    })
    @ResponseBody
    @RequestMapping(value = "/order/refund", method = RequestMethod.POST)
    public String insertOrUpdate(String orderNo, String accessToken, String fundCause) {
        UserInfo user = userDao.getUserByToken(accessToken);
        Order order = orderDAO.findByOrderNo(orderNo);
        RefundMoney rm = new RefundMoney();
        rm.setCreateDate(new Date());
        rm.setFundCause(fundCause);
        rm.setMoney(order.getTotalFee());
        rm.setPaymenOrderNo(orderNo);
        rm.setState(0);
        rm.setName(user.getName());
        rm.setRefundNo(OrderUtil.getNumberForPK());
        rm.setPhoneNumber(user.getTel());
        rm.setExamineFlow(0);
        String code = "2";
        String msg = "处理异常！";
        if (user != null) {
            if (order.getUid().equals(user.getUid())) {
                if (!order.getOrderStatus().equals(PayStatus.unpaid.getName())) {
                    if (!order.getOrderStatus().equals(PayStatus.refund.getName())) {
                        if (!order.getOrderStatus().equals(PayStatus.refundsuccess.getName())) {
                            if (!order.getOrderStatus().equals(PayStatus.refundsuccess.getName())) {
                                try {
                                    rm.setChannel(order.getPayType());
                                    // 执行操作
                                    refundMoneyService.saveOrUpdate(rm);
                                    BeecloudPayUtil util = new BeecloudPayUtil();
                                    Map<String, Object> map = new HashMap<>();
                                    map.put("orderNo", order.getOrderNo());
                                    //util.BCRefundParamter(rm.getPaymenOrderNo(), rm.getRefundNo(), rm.getMoney(), map);
                                    order.setOrderStatus(PayStatus.refund.getName());
                                    orderDAO.saveOrUpdate(order);
                                    code = "1";
                                    msg = "申请退款记录成功！";
                                    // 记录日志
                                    LOG.debug("新增、更新退费记录成功！");
                                } catch (Exception e) {
                                    // 异常 记录日志
                                    e.printStackTrace();
                                    LOG.error("新增、更新退费记录失败！\n" + e);
                                }
                            } else {
                                code = "2";
                                msg = "该订单的退款申请已被拒绝，无法重复提交！";
                            }
                        } else {
                            code = "2";
                            msg = "该订单已退款，无法重复提交申请！";
                        }
                    } else {
                        code = "2";
                        msg = "该订单已提交退款申请，等待审核！";
                    }
                } else {
                    code = "2";
                    msg = "该订单还未支付，无法退款！";
                }
            } else {
                code = "2";
                msg = "该订单不属于该用户！";
            }
        } else {
            code = "2";
            msg = "token已失效！";
        }
        return resultMsg.mapToJson(code, msg, "");
    }

    /**
     * 确认收货
     *
     * @param id 订单ID
     * @return
     */
    @ApiOperation(value = " 确认收货", notes = "")
    @ResponseBody
    @RequestMapping(value = "/order/enter", method = RequestMethod.POST)
    public String enter(String id) {
        String code = "2";
        String msg = "处理异常!";
        Order order = orderDao.findByOrderNo(id);
        if (order != null) {
            order.setOrderStatus(PayStatus.uncommented.getName());
            orderDao.saveOrUpdate(order);
            code = "1";
            msg = "确认收货成功！";
        } else {
            msg = "确认收货异常！";
        }
        return resultMsg.mapToJson(code, msg, null);
    }

    /**
     * 积分抵用
     *
     * @param id 订单ID
     * @return
     */
    @ApiOperation(value = " 积分抵用", notes = "")
    @ResponseBody
    @RequestMapping(value = "/order/integral", method = RequestMethod.POST)
    public String integral(String accessToken, int id, int isIntegral) {
        String code = "2";
        String msg = "处理异常!";
        Map<String, Object> result = new HashMap<>();
        UserInfo user = userDao.getUserByToken(accessToken);
        List<Commodity> cList = new ArrayList<Commodity>();
        List<ShoppingCart> scList = new ArrayList<ShoppingCart>();
        int totalFee = 0;
        //查询购物车中得订单信息
        Commodity c = new Commodity();
        //查询购物车数据
        ShoppingCart sc = shoppingCartDao.find(id);
        scList.add(sc);
        c = commDao.find(sc.getCommodityId());
        //判断库存是否充足
        JSONArray jsonArray = JSONArray.fromObject(sc.getSelected());
        List jsonObject = JSONArray.toList(jsonArray);
        for (Object o : jsonObject) {
            JSONObject jo = JSONObject.fromObject(o);
            Property property = propertyDAO.find(Integer.parseInt(jo.get("propertiesID").toString()));
            if (sc.getCommodityNumber() > Integer.parseInt(property.getPropertyNum())) {
                code = "2";
                msg = property.getPropertyValue() + "：库存不足，无法购买！";
                return resultMsg.mapToJson(code, msg, null);
            }
        }
        //判断购买用户时候是端口用户
        if (user.isPort()) {
            //计算商品总金额
            int money = (int) (c.getCommodityPriceUser() * 100) * sc.getCommodityNumber() + (int) (c.getFreight() * 100);
            //累计总金额
            totalFee = totalFee + money;
            result.put("totalFee", totalFee / 100);
            code = "1";
            msg = "成功！";
        } else {
            //计算商品总金额
            int money = (int) (c.getCommodityPriceShop() * 100) * sc.getCommodityNumber() + (int) (c.getFreight() * 100);
            //累计总金额
            totalFee = totalFee + money;
            result.put("totalFee", totalFee / 100);
            code = "1";
            msg = "成功！";
        }
        if (isIntegral == 1) {
            //可抵用积分
            float integralTotal = user.getIntegral() / c.getIntegralConsumptionRatio();
            //最多抵扣积分
            int integralLimit = c.getIntegralSpendingLimit() / c.getIntegralConsumptionRatio();

            //int num = c.getIntegralSpendingLimit()-(int) integralTotal * 100;
            if (integralTotal > 0) {
                if (integralLimit > (int) integralTotal) {
                    totalFee = totalFee - (int) integralTotal * 100;
                    result.put("totalFeeInteral", totalFee / 100);
                } else {
                    totalFee = totalFee - integralLimit * 100;
                    result.put("totalFeeInteral", totalFee / 100);
                }
                code = "1";
                msg = "成功！";
            } else {
                msg = "无可抵用积分！";
            }

        }
        return resultMsg.mapToJson(code, msg, result);
    }
}

